library IEEE;
use IEEE.std_logic_1164.all;
entity scope_core is
	port(	cha_data: 			in std_logic_vector(7 downto 0);
			chb_data:			in std_logic_vector(7 downto 0);
			trigger_position:	in std_logic_vector(12 downto 0);
			trigger_voltage_level:in std_logic_vector(7 downto 0);
			trigger_mode:		in std_logic_vector(1 downto 0);
			trigger_source:		in std_logic;
			auto_trigger:		in std_logic;
			
			start_sample:		in std_logic;
			start_scan:			in std_logic;
			cha_fifo_rdreq:		in std_logic;
			cha_fifo_rdempty:	out std_logic;
			cha_fifo_rdfull:	out std_logic;
			cha_fifo_data:		out std_logic_vector(15 downto 0);
			chb_fifo_rdreq:		in std_logic;
			chb_fifo_rdempty:	out std_logic;
			chb_fifo_rdfull:	out std_logic;
			chb_fifo_data:		out std_logic_vector(15 downto 0);
			cur_state:			out std_logic_vector(7 downto 0);
			fifo_wrfull:			out std_logic;
			scope_clk:			in std_logic;
			ifclk:				in std_logic;
			rst:				in std_logic
	);
end scope_core;
architecture arch_scope_core of scope_core is
component rst_ctrl is
	port (
		rst_in: in std_logic;
		clk: in std_logic;
		rst_out: out std_logic;
		nrst_out: out std_logic
	);
end component;
component fifo_rdclk_gen is
	port(	scope_clk: in std_logic;
			ifclk: in std_logic;
			rdclk: out std_logic;
			rdclk_sel: in std_logic
	);
end component;
component trigger_controller is
	port ( cha_data: in std_logic_vector(7 downto 0);
			chb_data: in std_logic_vector(7 downto 0);
			trigger_source: in std_logic;
			trigger_voltage_level: in std_logic_vector(7 downto 0);
			mode:in std_logic_vector(1 downto 0);
			auto_trigger: in std_logic;
			trigger_enable:in std_logic;
			trigger_pulse: out std_logic;
			sys_clk: in std_logic;
			rst: in std_logic
	);
end component;
component pretrigger_gen is
	port ( 	trigger_position: in std_logic_vector(12 downto 0);
			counter_en:	in std_logic;
			pretrigger_pulse: out std_logic;
			sysclk: in std_logic;
			rst: in std_logic	
	);
end component;
component fifo_8k
	PORT
	(
		aclr		: IN STD_LOGIC  := '0';
		data		: IN STD_LOGIC_VECTOR (7 DOWNTO 0);
		rdclk		: IN STD_LOGIC ;
		rdreq		: IN STD_LOGIC ;
		wrclk		: IN STD_LOGIC ;
		wrreq		: IN STD_LOGIC ;
		q		: OUT STD_LOGIC_VECTOR (15 DOWNTO 0);
		rdempty		: OUT STD_LOGIC ;
		rdfull		: OUT STD_LOGIC ;
		rdusedw		: OUT STD_LOGIC_VECTOR (12 DOWNTO 0);
		wrempty		: OUT STD_LOGIC ;
		wrfull		: OUT STD_LOGIC ;
		wrusedw		: OUT STD_LOGIC_VECTOR (13 DOWNTO 0)
	);
end component;
signal pretrigger_done_flag:std_logic;
signal trigger_done_flag:std_logic;
signal fifo_wrfull_flag: std_logic;
signal cha_fifo_wrfull_flag:std_logic;
signal chb_fifo_wrfull_flag:std_logic;
signal fifo_wrclk_en:std_logic;
signal fifo_rdclk_en:std_logic;
signal fifo_rd_clock:std_logic;
signal fifo_rdclk_select:std_logic;
signal trigger_module_en:std_logic;
signal pretrigger_counter_en: std_logic;
signal scope_current_state:std_logic_vector(7 downto 0);
signal cha_fifo_read_request: std_logic;
signal chb_fifo_read_request: std_logic;
signal fifo_write_request: std_logic;
type states is (idle,sample,trigger,filling,scan);
signal pr_state,nx_state:states;
signal scope_rst:std_logic;
begin
    U1:rst_ctrl port map(
		rst_in => rst,
		clk => scope_clk,
		rst_out => scope_rst,
		nrst_out => open
	);
    process(scope_clk,scope_rst)
    begin
        if(scope_rst = '1' )then
            pr_state <= idle;
        elsif (scope_clk = '1' and scope_clk'event) then
            pr_state <= nx_state;
        end if;
    end process;
    process(pr_state,start_sample,start_scan,pretrigger_done_flag,trigger_done_flag,fifo_wrfull_flag)
    begin
        case pr_state is
            when idle =>
                cur_state <= x"01";
                if(start_scan = '1')then
                    nx_state <= scan;
                elsif(start_sample = '1') then
                    nx_state <= sample;
                else
                    nx_state <= pr_state;
                end if;
            when sample =>
                cur_state <= x"02";
                if(pretrigger_done_flag = '1') then
                    nx_state <= trigger;
                else
                    nx_state <= pr_state;
                end if;
            when trigger =>
                cur_state <= x"04";
                if(trigger_done_flag = '1') then
                    nx_state <= filling;
                else
                    nx_state <= pr_state;
                end if;
            when filling =>
                cur_state <= x"08";
                if(fifo_wrfull_flag = '1') then
                    nx_state <= idle;
                else
                    nx_state <= pr_state;
                end if;
            when scan =>
                cur_state <= x"10";
                nx_state <= pr_state;
        end case;
    end process;
	fifo_wrfull <= fifo_wrfull_flag;
	fifo_rdclk_select <= '1' when pr_state = trigger else '0';
	fifo_wrfull_flag <= cha_fifo_wrfull_flag and chb_fifo_wrfull_flag;
	trigger_module_en <= '1' when pr_state = trigger else '0';
	cha_fifo_read_request <= '1' when (pr_state = trigger or cha_fifo_rdreq = '1') else '0';
	chb_fifo_read_request <= '1' when (pr_state = trigger or chb_fifo_rdreq = '1') else '0';
	fifo_write_request <= '1' when pr_state /= idle else '0';
	pretrigger_counter_en <= '1' when pr_state = sample else '0';
	cha_fifo: fifo_8k port map(
		aclr => scope_rst,
		data => cha_data,
		rdclk => fifo_rd_clock,
		rdreq => cha_fifo_read_request,
		wrclk => scope_clk,
		wrreq => fifo_write_request,
		q => cha_fifo_data,
		rdempty => cha_fifo_rdempty,
		rdfull => cha_fifo_rdfull,
		rdusedw => open,
		wrempty => open,
		wrfull => cha_fifo_wrfull_flag,
		wrusedw => open
	);
	chb_fifo: fifo_8k port map(
		aclr => scope_rst,
		data => chb_data,
		rdclk => fifo_rd_clock,
		rdreq => chb_fifo_read_request,
		wrclk => scope_clk,
		wrreq => fifo_write_request,
		q => chb_fifo_data,
		rdempty => chb_fifo_rdempty,
		rdfull => chb_fifo_rdfull,
		rdusedw => open,
		wrempty => open,
		wrfull => chb_fifo_wrfull_flag,
		wrusedw => open
	);

	U3: fifo_rdclk_gen port map(
		scope_clk => scope_clk,
		ifclk => ifclk,
		rdclk => fifo_rd_clock,
		rdclk_sel => fifo_rdclk_select
	);
	U4: trigger_controller port map(
		cha_data => cha_data,
		chb_data => chb_data,
		trigger_source => trigger_source,
		trigger_voltage_level => trigger_voltage_level,
		mode => trigger_mode,
		auto_trigger => auto_trigger,
		trigger_enable => trigger_module_en,
		trigger_pulse => trigger_done_flag,
		sys_clk => scope_clk,
		rst => scope_rst
		);
	U5: pretrigger_gen port map(
		trigger_position => trigger_position,
		counter_en => pretrigger_counter_en,
		pretrigger_pulse => pretrigger_done_flag,
		sysclk => scope_clk,
		rst => scope_rst
	);
end arch_scope_core;